package com.epam.ws.anatomist.message;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import com.epam.ws.anatomist.common.WsAnatomistUtil;
import com.epam.ws.anatomist.common.exception.ErrorMessages;
import com.epam.ws.anatomist.common.exception.ResourceProcessingException;

import freemarker.template.Template;
import freemarker.template.TemplateException;

public class MessageBuilder
{

	private static final Logger LOGGER = Logger.getLogger(MessageBuilder.class);

	public static <T> T buildPojoEntity(TemplatePojoEntity message)
	{
		return buildPojoEntity(message.getPojoType(), message.getTemplateEntity());
	}

	public static String buildXmlMessage(TemplateEntity message)
	{
		return buildXmlMessage(message.getTemplate(), message.getDataSource());
	}

	public static <T> T buildPojoEntity(Class<?> pojoType, TemplateEntity message)
	{
		return buildPojoEntity(pojoType, message.getTemplate(), message.getDataSource());
	}

	public static <T> T buildPojoEntity(Class<T> pojoType, String resourcePath)
	{
		return (T) MessageConverter.convertXmlToPojo(pojoType, buildXmlMessage(resourcePath));
	}

	@SuppressWarnings("unchecked")
	public static <T> T buildPojoEntity(Class<?> pojoType, Template template, Properties dataSource)
	{
		String content = buildXmlMessage(template, dataSource);
		return (T) MessageConverter.convertXmlToPojo(pojoType, content);
	}

	public static String buildXmlMessage(String resourcePath)
	{
		InputStream is = WsAnatomistUtil.getResourceAsStream(resourcePath);
		try
		{
			String xml = IOUtils.toString(is);
			return xml;
		}
		catch (IOException e)
		{
			LOGGER.error(ErrorMessages.RESOURCE_READING_ERROR);
			throw new ResourceProcessingException(ErrorMessages.RESOURCE_READING_ERROR);
		}
		finally
		{
			IOUtils.closeQuietly(is);
		}
	}

	public static String buildXmlMessage(Template template, Properties dataSource)
	{
		StringWriter writer = new StringWriter();
		try
		{
			template.process(dataSource, writer);
			return writer.toString();
		}
		catch (TemplateException e)
		{
			LOGGER.error(ErrorMessages.TEMPLATE_PROCESSING_ERROR);
			throw new ResourceProcessingException(ErrorMessages.TEMPLATE_PROCESSING_ERROR);
		}
		catch (IOException e)
		{
			LOGGER.error(ErrorMessages.RESOURCE_READING_ERROR);
			throw new ResourceProcessingException(ErrorMessages.RESOURCE_READING_ERROR);
		}
		finally
		{
			IOUtils.closeQuietly(writer);
		}
	}

}
